package com.example.service.impl;

import com.example.common.Result;
import com.example.dto.MenuPermissionDTO;
import com.example.entity.MenuPermission;
import com.example.entity.RoleMenu;
import com.example.entity.RolePermission;
import com.example.mapper.MenuPermissionMapper;
import com.example.mapper.RoleMenuMapper;
import com.example.mapper.RolePermissionMapper;
import com.example.service.MenuPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 菜单权限绑定服务实现
 */
@Service
public class MenuPermissionServiceImpl implements MenuPermissionService {

    @Autowired
    private MenuPermissionMapper menuPermissionMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Override
    @Transactional
    public Result<String> bindPermissionsToMenu(MenuPermissionDTO dto) {
        try {
            if (dto.getMenuId() == null) {
                return Result.error("菜单ID不能为空");
            }

            // 先删除该菜单的所有权限绑定
            menuPermissionMapper.deleteByMenuId(dto.getMenuId());

            int bindCount = 0;
            // 如果权限ID列表不为空，则新增权限绑定
            if (dto.getPermissionIds() != null && !dto.getPermissionIds().isEmpty()) {
                for (Long permissionId : dto.getPermissionIds()) {
                    MenuPermission menuPermission = new MenuPermission();
                    menuPermission.setMenuId(dto.getMenuId());
                    menuPermission.setPermissionId(permissionId);
                    menuPermission.setCreateTime(LocalDateTime.now());
                    menuPermission.setDeleted(0);
                    menuPermissionMapper.insert(menuPermission);
                    bindCount++;
                }

                // 如果启用自动分配给相关角色
                if (dto.getAutoAssignToRoles() != null && dto.getAutoAssignToRoles()) {
                    syncRolePermissions(dto.getMenuId());
                }
            }

            return Result.success("菜单权限绑定成功，共绑定 " + bindCount + " 个权限");
        } catch (Exception e) {
            return Result.error("菜单权限绑定失败：" + e.getMessage());
        }
    }

    @Override
    public Result<List<Long>> getMenuPermissions(Long menuId) {
        try {
            List<MenuPermission> menuPermissions = menuPermissionMapper.selectByMenuId(menuId);
            List<Long> permissionIds = menuPermissions.stream()
                    .map(MenuPermission::getPermissionId)
                    .collect(Collectors.toList());
            return Result.success(permissionIds);
        } catch (Exception e) {
            return Result.error("查询菜单权限失败：" + e.getMessage());
        }
    }

    @Override
    public Result<List<Long>> getPermissionMenus(Long permissionId) {
        try {
            List<MenuPermission> menuPermissions = menuPermissionMapper.selectByPermissionId(permissionId);
            List<Long> menuIds = menuPermissions.stream()
                    .map(MenuPermission::getMenuId)
                    .collect(Collectors.toList());
            return Result.success(menuIds);
        } catch (Exception e) {
            return Result.error("查询权限菜单失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<String> removeMenuPermissions(Long menuId) {
        try {
            menuPermissionMapper.deleteByMenuId(menuId);
            return Result.success("删除菜单权限绑定成功");
        } catch (Exception e) {
            return Result.error("删除菜单权限绑定失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<String> removePermissionMenus(Long permissionId) {
        try {
            menuPermissionMapper.deleteByPermissionId(permissionId);
            return Result.success("删除权限菜单绑定成功");
        } catch (Exception e) {
            return Result.error("删除权限菜单绑定失败：" + e.getMessage());
        }
    }

    @Override
    public Result<Boolean> checkMenuPermissionExists(Long menuId, Long permissionId) {
        try {
            boolean exists = menuPermissionMapper.existsByMenuIdAndPermissionId(menuId, permissionId);
            return Result.success(exists);
        } catch (Exception e) {
            return Result.error("检查菜单权限绑定失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<String> batchBindPermissionsToMenus(List<Long> menuIds, List<Long> permissionIds) {
        try {
            if (menuIds == null || menuIds.isEmpty()) {
                return Result.error("菜单ID列表不能为空");
            }
            if (permissionIds == null || permissionIds.isEmpty()) {
                return Result.error("权限ID列表不能为空");
            }

            int bindCount = 0;
            for (Long menuId : menuIds) {
                // 先删除该菜单的所有权限绑定
                menuPermissionMapper.deleteByMenuId(menuId);

                // 为每个菜单绑定所有权限
                for (Long permissionId : permissionIds) {
                    MenuPermission menuPermission = new MenuPermission();
                    menuPermission.setMenuId(menuId);
                    menuPermission.setPermissionId(permissionId);
                    menuPermission.setCreateTime(LocalDateTime.now());
                    menuPermission.setDeleted(0);
                    menuPermissionMapper.insert(menuPermission);
                    bindCount++;
                }

                // 同步角色权限
                syncRolePermissions(menuId);
            }

            return Result.success("批量菜单权限绑定成功，共绑定 " + bindCount + " 个关联");
        } catch (Exception e) {
            return Result.error("批量菜单权限绑定失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<String> syncRolePermissions(Long menuId) {
        try {
            // 获取有该菜单权限的所有角色
            List<RoleMenu> roleMenus = roleMenuMapper.selectByMenuId(menuId);
            if (roleMenus.isEmpty()) {
                return Result.success("无相关角色，无需同步");
            }

            // 获取该菜单绑定的所有权限
            List<MenuPermission> menuPermissions = menuPermissionMapper.selectByMenuId(menuId);
            if (menuPermissions.isEmpty()) {
                return Result.success("菜单无绑定权限，无需同步");
            }

            List<Long> permissionIds = menuPermissions.stream()
                    .map(MenuPermission::getPermissionId)
                    .collect(Collectors.toList());

            int syncCount = 0;
            // 为每个拥有该菜单的角色分配对应权限
            for (RoleMenu roleMenu : roleMenus) {
                Long roleId = roleMenu.getRoleId();

                // 获取角色已有的权限，避免重复分配
                List<RolePermission> existingRolePermissions = rolePermissionMapper.selectByRoleId(roleId);
                Set<Long> existingPermissionIds = existingRolePermissions.stream()
                        .map(RolePermission::getPermissionId)
                        .collect(Collectors.toSet());

                // 为角色分配新权限
                for (Long permissionId : permissionIds) {
                    if (!existingPermissionIds.contains(permissionId)) {
                        RolePermission rolePermission = new RolePermission();
                        rolePermission.setRoleId(roleId);
                        rolePermission.setPermissionId(permissionId);
                        rolePermission.setCreateTime(LocalDateTime.now());
                        rolePermission.setDeleted(0);
                        rolePermissionMapper.insert(rolePermission);
                        syncCount++;
                    }
                }
            }

            return Result.success("同步角色权限成功，新增 " + syncCount + " 个权限分配");
        } catch (Exception e) {
            return Result.error("同步角色权限失败：" + e.getMessage());
        }
    }
} 